// 设置蛇🐍

class Snake {
  // 获取蛇的容器
  element: HTMLElement
  // 表示蛇头的元素
  head: HTMLElement
  // 蛇的身体（包括蛇头）
  bodies: HTMLCollection;

  constructor() {
    this.element = document.getElementById('snake')!
    this.head = document.querySelector('#snake>div') as HTMLElement
    this.bodies = this.element.getElementsByTagName('div')
  }

  // 获取蛇头的x坐标（蛇头坐标）
  get X() {
    return this.head.offsetLeft
  }
  // 获取蛇的y坐标（蛇头坐标）
  get Y() {
    return this.head.offsetTop
  }

  // 设置蛇头x坐标
  set X(value) {

    // 如果新值和旧值相同，则直接返回不再修改
    if (this.X === value) {
      return;
    }

    // X的值的合法范围0-290之间
    // 撞墙就报错，游戏结束！！
    if (value < 0 || value > 290) {
      throw new Error("撞墙了！游戏结束！");
    }

    // 左右移动时，不能原地掉头
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
      // this.bodies[1] 有身体
      if (value > this.X) {
        value = this.X - 10
      } else {
        value = this.X + 10
      }
    }

    // 蛇身体移动
    this.moveBody()

    // 蛇头移动
    this.head.style.left = value + 'px'

    // 检查撞到自己没有
    this.checkHeadEatBody()
  }
  // 设置蛇头y坐标
  set Y(value) {
    // 如果新值和旧值相同，则直接返回不再修改
    if (this.Y === value) {
      return;
    }

    // 撞墙就报错，游戏结束！！
    if (value < 0 || value > 290) {
      throw new Error("撞墙了！游戏结束！");
    }

    // 左右移动时，不能原地掉头
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
      // this.bodies[1] 有身体
      if (value > this.Y) {
        value = this.Y - 10
      } else {
        value = this.Y + 10
      }
    }

    // 蛇身体移动
    this.moveBody()

    // 蛇头移动
    this.head.style.top = value + 'px'

    // 检查撞到自己没有
    this.checkHeadEatBody()
  }

  // 蛇增加长度
  addBody() {
    // 蛇的容器  element: HTMLElement 中，增加一个div
    this.element.insertAdjacentHTML("beforeend", "<div></div>")
  }

  // 蛇身体移动
  moveBody() {
    // 先移动尾巴，最后移动头（但是此处不控制蛇头，蛇头在GameControl组件里面，控制XY坐标即可）

    // 遍历所有的身体div
    for (let i = this.bodies.length - 1; i > 0; i--) {
      // 获取前面一个div的坐标，赋值给最后面一个div

      // 获取坐标
      let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
      let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

      // 赋值坐标
      (this.bodies[i] as HTMLElement).style.left = X + 'px';
      (this.bodies[i] as HTMLElement).style.top = Y + 'px';
    }
  }

  // 判断是否蛇头吃到身体
  checkHeadEatBody() {
    // 获取所有身体的坐标，如果和蛇头坐标相等，那就表示撞到身体了
    for (let i = 1; i < this.bodies.length; i++) {
      let body = this.bodies[i] as HTMLElement
      if (body.offsetLeft === this.X && body.offsetTop === this.Y) {
        throw new Error("吃到自己了");
      }
    }
  }

}




export default Snake
